﻿//++
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
// Module Name:
//
//  DispatcherTestClassFactory.cs
//    
// Abstract:
//
//  This module extends DispatcherClassFactory and returns mock instances
//  of classees with external dependencies for easy testibility.
//
//--

using System;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Security.Permissions;

namespace Microsoft.EnhancedReminders.Dispatcher.UnitTests
{
    /// <summary>
    /// Extension of DispatcherClass factory that returns mock instances of IMessageSender and
    /// IPresenceProvider for easy unit testing.
    /// 
    /// Each test case should use its own instance of this class if possible, as some of the
    /// mock objects are single instances exposed for the sake of the test.
    /// </summary>
    public class DispatcherTestClassFactory : DispatcherClassFactory
    {
        private MockPresenceProvider _presenceProvider;
        private IDictionary<string, string> _mockActiveDirectory;

        /// <summary>
        /// The presence provider used by the class factory.
        /// </summary>
        public MockPresenceProvider PresenceProvider
        {
            get { return _presenceProvider; }
            set { _presenceProvider = value; }
        }
        
        /// <summary>
        /// ctor.
        /// </summary>
        public DispatcherTestClassFactory()
        {
            _presenceProvider = new MockPresenceProvider();
            _mockActiveDirectory = new Dictionary<string, string>();
        }

        /// <summary>
        /// Begin initializing the SIP Endpoint. Since no endpoint is used, this doesn't do anything.
        /// </summary>
        public override void Initialize()
        {
            // do nothing. The unit tests aren't interested in the callback.
        }

        /// <summary>
        /// Returns a new instance of InstantMessageSender using MockInstantMessenger for 
        /// delivering instant messages.
        /// </summary>
        public override IMessageSender CreateMessageSender(NotificationItem notification, PresenceObtainedEventArgs contactCard)
        {
            // this is not called by any unit tests specifically, but any unit tests that test
            // the Dispatcher class may call CreateMessageSender, so we need to override the base
            // version.
            return null;
        }

        /// <summary>
        /// Returns a new instance of MockPresenceProvider.
        /// </summary>
        public override IPresenceProvider CreatePresenceProvider()
        {
            return PresenceProvider;
        }

        /// <summary>
        /// Obtains a sip address based on the e-mail address in the notficiation item. This
        /// is obtained from an internal dictionary.
        /// </summary>
        [EnvironmentPermission(SecurityAction.LinkDemand, Unrestricted=true)]
        public override string ObtainSipAddress(NotificationItem notification)
        {
            if (_mockActiveDirectory.ContainsKey(notification.EmailAddress))
            {
                return _mockActiveDirectory[notification.EmailAddress];
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// Add a test user to the mock AD and presence provider for simulating user state.
        /// </summary>
        public void AddMockUser(string email, string sipAddress, PresenceStates presence)
        {
            Assert.IsFalse(_mockActiveDirectory.ContainsKey(email), "Test bug: email address already found in mock AD");
            Assert.IsFalse(PresenceProvider.PresenceStateMap.ContainsKey(sipAddress), "Test bug: sip address already found in presence map");

            _mockActiveDirectory.Add(email, sipAddress);
            PresenceProvider.PresenceStateMap.Add(sipAddress, presence);
        }
    }
}
